<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='Ext-dd-DragTracker'>/**
</span> * @class Ext.dd.DragTracker
 * @extends Ext.util.Observable
 * A DragTracker listens for drag events on an Element and fires events at the start and end of the drag,
 * as well as during the drag. This is useful for components such as {@link Ext.slider.MultiSlider}, where there is
 * an element that can be dragged around to change the Slider's value.
 * DragTracker provides a series of template methods that should be overridden to provide functionality
 * in response to detected drag operations. These are onBeforeStart, onStart, onDrag and onEnd.
 * See {@link Ext.slider.MultiSlider}'s initEvents function for an example implementation.
 */
Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {    
<span id='Ext-dd-DragTracker-cfg-active'>    /**
</span>     * @cfg {Boolean} active
	 * Defaults to &lt;tt&gt;false&lt;/tt&gt;.
	 */	
    active: false,
<span id='Ext-dd-DragTracker-cfg-tolerance'>    /**
</span>     * @cfg {Number} tolerance
	 * Number of pixels the drag target must be moved before dragging is considered to have started. Defaults to &lt;tt&gt;5&lt;/tt&gt;.
	 */	
    tolerance: 5,
<span id='Ext-dd-DragTracker-cfg-autoStart'>    /**
</span>     * @cfg {Boolean/Number} autoStart
	 * Defaults to &lt;tt&gt;false&lt;/tt&gt;. Specify &lt;tt&gt;true&lt;/tt&gt; to defer trigger start by 1000 ms.
	 * Specify a Number for the number of milliseconds to defer trigger start.
	 */	
    autoStart: false,
    
<span id='Ext-dd-DragTracker-method-constructor'>    constructor : function(config){
</span>        Ext.apply(this, config);
	    this.addEvents(
<span id='Ext-dd-DragTracker-event-mousedown'>	        /**
</span>	         * @event mousedown
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'mousedown',
<span id='Ext-dd-DragTracker-event-mouseup'>	        /**
</span>	         * @event mouseup
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'mouseup',
<span id='Ext-dd-DragTracker-event-mousemove'>	        /**
</span>	         * @event mousemove
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'mousemove',
<span id='Ext-dd-DragTracker-event-dragstart'>	        /**
</span>	         * @event dragstart
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'dragstart',
<span id='Ext-dd-DragTracker-event-dragend'>	        /**
</span>	         * @event dragend
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'dragend',
<span id='Ext-dd-DragTracker-event-drag'>	        /**
</span>	         * @event drag
	         * @param {Object} this
	         * @param {Object} e event object
	         */
	        'drag'
	    );
	
	    this.dragRegion = new Ext.lib.Region(0,0,0,0);
	
	    if(this.el){
	        this.initEl(this.el);
	    }
        Ext.dd.DragTracker.superclass.constructor.call(this, config);
    },

<span id='Ext-dd-DragTracker-method-initEl'>    initEl: function(el){
</span>        this.el = Ext.get(el);
        el.on('mousedown', this.onMouseDown, this,
                this.delegate ? {delegate: this.delegate} : undefined);
    },

<span id='Ext-dd-DragTracker-method-destroy'>    destroy : function(){
</span>        this.el.un('mousedown', this.onMouseDown, this);
        delete this.el;
    },

<span id='Ext-dd-DragTracker-method-onMouseDown'>    onMouseDown: function(e, target){
</span>        if(this.fireEvent('mousedown', this, e) !== false &amp;&amp; this.onBeforeStart(e) !== false){
            this.startXY = this.lastXY = e.getXY();
            this.dragTarget = this.delegate ? target : this.el.dom;
            if(this.preventDefault !== false){
                e.preventDefault();
            }
            Ext.getDoc().on({
                scope: this,
                mouseup: this.onMouseUp,
                mousemove: this.onMouseMove,
                selectstart: this.stopSelect
            });
            if(this.autoStart){
                this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
            }
        }
    },

<span id='Ext-dd-DragTracker-method-onMouseMove'>    onMouseMove: function(e, target){
</span>        // HACK: IE hack to see if button was released outside of window. Resolved in IE9.
        var ieCheck = Ext.isIE6 || Ext.isIE7 || Ext.isIE8;
        if(this.active &amp;&amp; ieCheck &amp;&amp; !e.browserEvent.button){
            e.preventDefault();
            this.onMouseUp(e);
            return;
        }

        e.preventDefault();
        var xy = e.getXY(), s = this.startXY;
        this.lastXY = xy;
        if(!this.active){
            if(Math.abs(s[0]-xy[0]) &gt; this.tolerance || Math.abs(s[1]-xy[1]) &gt; this.tolerance){
                this.triggerStart(e);
            }else{
                return;
            }
        }
        this.fireEvent('mousemove', this, e);
        this.onDrag(e);
        this.fireEvent('drag', this, e);
    },

<span id='Ext-dd-DragTracker-method-onMouseUp'>    onMouseUp: function(e) {
</span>        var doc = Ext.getDoc(),
            wasActive = this.active;
            
        doc.un('mousemove', this.onMouseMove, this);
        doc.un('mouseup', this.onMouseUp, this);
        doc.un('selectstart', this.stopSelect, this);
        e.preventDefault();
        this.clearStart();
        this.active = false;
        delete this.elRegion;
        this.fireEvent('mouseup', this, e);
        if(wasActive){
            this.onEnd(e);
            this.fireEvent('dragend', this, e);
        }
    },

<span id='Ext-dd-DragTracker-method-triggerStart'>    triggerStart: function(e) {
</span>        this.clearStart();
        this.active = true;
        this.onStart(e);
        this.fireEvent('dragstart', this, e);
    },

<span id='Ext-dd-DragTracker-method-clearStart'>    clearStart : function() {
</span>        if(this.timer){
            clearTimeout(this.timer);
            delete this.timer;
        }
    },

<span id='Ext-dd-DragTracker-method-stopSelect'>    stopSelect : function(e) {
</span>        e.stopEvent();
        return false;
    },
    
<span id='Ext-dd-DragTracker-method-onBeforeStart'>    /**
</span>     * Template method which should be overridden by each DragTracker instance. Called when the user first clicks and
     * holds the mouse button down. Return false to disallow the drag
     * @param {Ext.EventObject} e The event object
     */
    onBeforeStart : function(e) {

    },

<span id='Ext-dd-DragTracker-method-onStart'>    /**
</span>     * Template method which should be overridden by each DragTracker instance. Called when a drag operation starts
     * (e.g. the user has moved the tracked element beyond the specified tolerance)
     * @param {Ext.EventObject} e The event object
     */
    onStart : function(xy) {

    },

<span id='Ext-dd-DragTracker-method-onDrag'>    /**
</span>     * Template method which should be overridden by each DragTracker instance. Called whenever a drag has been detected.
     * @param {Ext.EventObject} e The event object
     */
    onDrag : function(e) {

    },

<span id='Ext-dd-DragTracker-method-onEnd'>    /**
</span>     * Template method which should be overridden by each DragTracker instance. Called when a drag operation has been completed
     * (e.g. the user clicked and held the mouse down, dragged the element and then released the mouse button)
     * @param {Ext.EventObject} e The event object
     */
    onEnd : function(e) {

    },

<span id='Ext-dd-DragTracker-method-getDragTarget'>    /**
</span>     * Returns the drag target
     * @return {Ext.Element} The element currently being tracked
     */
    getDragTarget : function(){
        return this.dragTarget;
    },

<span id='Ext-dd-DragTracker-method-getDragCt'>    getDragCt : function(){
</span>        return this.el;
    },

<span id='Ext-dd-DragTracker-method-getXY'>    getXY : function(constrain){
</span>        return constrain ?
               this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
    },

<span id='Ext-dd-DragTracker-method-getOffset'>    getOffset : function(constrain){
</span>        var xy = this.getXY(constrain),
            s = this.startXY;
        return [s[0]-xy[0], s[1]-xy[1]];
    },

<span id='Ext-dd-DragTracker-property-constrainModes'>    constrainModes: {
</span>        'point' : function(xy){

            if(!this.elRegion){
                this.elRegion = this.getDragCt().getRegion();
            }

            var dr = this.dragRegion;

            dr.left = xy[0];
            dr.top = xy[1];
            dr.right = xy[0];
            dr.bottom = xy[1];

            dr.constrainTo(this.elRegion);

            return [dr.left, dr.top];
        }
    }
});</pre>
</body>
</html>
